너는 딥러닝, 인공신경망, 자연어처리,
뉴스기사 분류, 단일 레이블 다중분류,
TensorFlow·Keras, 모델 성능평가,
데이터 시각화 및 Python 코딩을 전문적으로 수행하는
데이터 분석가이자 대학 교육 전문가이다.

TensorFlow·Keras에서 제공하는 Reuters 뉴스 데이터셋을 이용하여
각 뉴스 기사를 46개의 상호 배타적인 토픽 중 하나로 분류하는
완전연결 심층신경망(DNN) 분석을 수행하여라.

본 실습은 첨부 교재의 기본흐름을 유지하면서
데이터 구조 확인, 뉴스 기사 복원,
멀티-핫 입력 변환, 신경망 학습,
과적합 진단, 시험성능 평가,
토픽별 성능과 오분류 분석,
병목층 비교 및 모델 개선까지 수행한다.

────────────────────────────────────
[가장 중요한 실행 원칙]
────────────────────────────────────

- 개념만 설명하거나 Python 코드만 작성하고 종료하지 마라.
- 반드시 Python 코드를 실제 Python 실행환경에서 실행하여라.
- 실제 실행으로 얻은 수치, 표 및 그래프를 확인한 후 해석하여라.
- Accuracy, Loss, 혼동행렬, F1-score 및 예측결과를
  임의로 만들거나 예시값으로 제시하지 마라.
- 코드 오류가 발생하면 원인을 확인하고 수정한 뒤 다시 실행하여라.
- 모든 최종 결론은 실제 Python 실행결과만을 근거로 작성하여라.
- 시험자료는 모델구조, Epoch 및 하이퍼파라미터 선택에 사용하지 마라.
- 훈련자료에서 검증자료를 별도로 구성하여라.
- 토픽별 클래스 분포를 먼저 확인한 뒤
  가능한 경우 층화분할을 사용하여라.
- 일부 토픽의 표본 수가 부족하여 층화분할이 불가능하면
  그 이유를 설명하고 합리적인 대안을 적용하여라.
- 뉴스 기사 입력은 여러 단어 위치가 동시에 1이므로
  원-핫 입력이 아니라 멀티-핫 입력이라고 설명하여라.
- 하나의 기사에 하나의 토픽만 부여되므로
  단일 레이블 다중분류라고 설명하여라.
- 46개의 독립적인 이진분류 문제가 아니라
  상호 배타적인 46개 클래스 중 하나를 선택하는 문제임을 명시하여라.
- 출력층은 Dense(46, softmax)를 사용하여라.
- Softmax 확률합이 1인지 실제로 확인하여라.
- 클래스 불균형이 있으므로 Accuracy만으로 평가하지 마라.
- Macro F1, Weighted F1, 클래스별 Recall 및 Top-k Accuracy를 추가하여라.
- 과적합은 훈련·검증 Loss와 Accuracy 곡선으로 판단하여라.
- 9 Epoch를 고정하지 말고 실제 검증손실 최솟값을 확인하여라.
- 토픽 이름이 데이터에 제공되지 않으면
  Topic 0~Topic 45로 표시하고 실제 명칭을 임의로 만들지 마라.
- import는 tensorflow.keras 방식으로 통일하여라.
- 난수 seed를 고정하여 재현성을 확보하여라.

────────────────────────────────────
1. 분석 목적
────────────────────────────────────

본 분석의 목적은 다음과 같다.

1. 로이터 뉴스 데이터의 구조를 이해한다.
2. 정수 인덱스로 표현된 뉴스를 실제 영어 단어로 복원한다.
3. 가변 길이 뉴스기사를 10,000차원 고정 입력으로 변환한다.
4. 46개 뉴스 토픽을 분류하는 DNN을 구축한다.
5. 단일 레이블 다중분류의 개념을 이해한다.
6. ReLU와 Softmax 활성화 함수의 역할을 이해한다.
7. Categorical Cross-Entropy의 의미를 이해한다.
8. 훈련·검증곡선으로 과적합 시점을 확인한다.
9. 시험자료에서 Accuracy와 Macro F1을 평가한다.
10. 토픽별 Precision·Recall·F1을 비교한다.
11. 자주 혼동되는 토픽쌍을 분석한다.
12. 소수 토픽의 성능을 별도로 확인한다.
13. 병목층 크기에 따른 성능 변화를 비교한다.
14. 새로운 뉴스 기사의 토픽을 예측한다.

────────────────────────────────────
2. 첨부 교재의 기본구조
────────────────────────────────────

첨부 교재의 흐름은 다음과 같다.

- Reuters 데이터 불러오기
- 훈련자료 8,982개
- 시험자료 2,246개
- 상위 10,000개 단어 사용
- 기사별 정수 인덱스 시퀀스 확인
- 인덱스를 영어 단어로 복원
- 기사 입력을 10,000차원 멀티-핫 벡터로 변환
- 레이블을 46차원 원-핫 벡터로 변환
- Dense 64 + ReLU
- Dense 64 + ReLU
- Dense 46 + Softmax
- RMSprop
- Categorical Cross-Entropy
- 훈련자료 중 1,000개를 검증자료로 사용
- 20 Epoch 학습
- 훈련·검증 Loss와 Accuracy 확인
- 약 9 Epoch 이후 과적합 판단
- 9 Epoch로 다시 학습
- 시험 정확도 평가
- 46개 토픽 예측확률 확인
- Dense 4 병목층 비교

현재 실습에서는 위 흐름을 재현하되,
실제 실행결과를 기준으로 최적 Epoch를 결정하여라.

────────────────────────────────────
3. 실행환경 확인
────────────────────────────────────

Python으로 다음을 실제 출력하여라.

- Python 버전
- TensorFlow 버전
- Keras 버전
- NumPy 버전
- pandas 버전
- scikit-learn 버전
- GPU 사용 가능 여부
- GPU 장치명

다음 방식으로 import를 통일하여라.

import random
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
import tensorflow as tf

from tensorflow import keras
from tensorflow.keras import layers

난수 seed:

SEED = 42

random.seed(SEED)
np.random.seed(SEED)
tf.random.set_seed(SEED)

────────────────────────────────────
4. Reuters 데이터 불러오기
────────────────────────────────────

다음 코드로 데이터를 불러와라.

from tensorflow.keras.datasets import reuters

(train_data, train_labels), (test_data, test_labels) = \
    reuters.load_data(num_words=10000)

다음을 실제 출력하여라.

- train_data 길이
- train_labels 길이
- test_data 길이
- test_labels 길이
- 첫 번째 뉴스의 정수 시퀀스
- 열 번째 뉴스의 정수 시퀀스
- 첫 번째 뉴스의 토픽
- 열 번째 뉴스의 토픽
- 레이블 최솟값과 최댓값
- 고유 클래스 수
- 가장 큰 단어 인덱스
- 가장 작은 단어 인덱스

기대구조:

- 훈련자료: 8,982개
- 시험자료: 2,246개
- 클래스: 0~45
- 토픽 수: 46개

실제 실행결과를 기준으로 확인하여라.

────────────────────────────────────
5. 단일 레이블 다중분류
────────────────────────────────────

다음을 설명하여라.

단일 레이블 다중분류:

- 하나의 뉴스 기사
- 정확히 하나의 토픽
- 46개의 토픽 중 하나 선택

다중 레이블 분류:

- 하나의 뉴스 기사
- 여러 토픽을 동시에 가질 수 있음

본 Reuters 데이터는 단일 레이블 다중분류이다.

출력층:

- 46개 노드
- Softmax
- 확률합 1
- 가장 큰 확률의 인덱스가 최종 예측 토픽

────────────────────────────────────
6. 클래스 분포 분석
────────────────────────────────────

각 토픽별 훈련자료와 시험자료 수를 계산하여라.

다음 표를 작성하여라.

| Topic | Train Count | Test Count | Train Ratio | Test Ratio |
|------|-------------|------------|-------------|------------|

다음을 실제 확인하여라.

- 가장 많은 토픽
- 가장 적은 토픽
- 훈련자료 기준 상위 10개 토픽
- 훈련자료 기준 하위 10개 토픽
- 각 토픽의 최소 표본 수
- 훈련과 시험의 토픽 분포 차이
- 시험자료에 존재하지 않는 토픽
- 시험자료 표본이 5개 미만인 토픽

다음 그래프를 작성하여라.

1. 토픽별 훈련자료 수
2. 토픽별 시험자료 수
3. 로그축 클래스 분포
4. 상위 10개와 하위 10개 토픽 비교

클래스 불균형이 Accuracy에 미치는 영향을 설명하여라.

────────────────────────────────────
7. 뉴스 기사 길이 분석
────────────────────────────────────

각 뉴스의 단어 수를 계산하여라.

다음을 실제 계산하여라.

- 평균 길이
- 중앙값
- 표준편차
- 최솟값
- 최댓값
- 25%, 50%, 75%, 90%, 95%, 99% 분위수
- 토픽별 평균 뉴스 길이
- 토픽별 중앙 뉴스 길이

그래프:

- 뉴스 길이 Histogram
- 뉴스 길이 Boxplot
- 토픽별 평균 뉴스 길이
- 정분류·오분류 뉴스 길이 비교

뉴스 길이가 토픽 분류의 직접 원인이라고 단정하지 마라.

────────────────────────────────────
8. 단어 인덱스와 뉴스 복원
────────────────────────────────────

다음 코드를 사용하여라.

word_index = reuters.get_word_index()

reverse_word_index = {
    value: key
    for key, value in word_index.items()
}

def decode_newswire(sequence):
    return " ".join(
        reverse_word_index.get(index - 3, "?")
        for index in sequence
    )

다음 뉴스를 실제로 복원하여라.

- 첫 번째 훈련 뉴스
- 열 번째 훈련 뉴스
- 임의의 뉴스 5개
- 가장 긴 뉴스
- 가장 짧은 뉴스
- 표본 수가 가장 많은 토픽의 뉴스
- 표본 수가 가장 적은 토픽의 뉴스

각 뉴스와 함께 다음을 표시하여라.

- 뉴스 번호
- 실제 Topic 번호
- 단어 수
- 복원된 뉴스 일부

토픽의 실제 명칭이 데이터에 제공되지 않으면
Topic 번호만 표시하여라.

────────────────────────────────────
9. 입력자료 멀티-핫 벡터화
────────────────────────────────────

다음 함수를 사용하여라.

def vectorize_sequences(sequences, dimension=10000):
    results = np.zeros(
        (len(sequences), dimension),
        dtype="float32"
    )

    for i, sequence in enumerate(sequences):
        results[i, sequence] = 1.0

    return results

x_train = vectorize_sequences(train_data)
x_test = vectorize_sequences(test_data)

다음을 실제 출력하여라.

- x_train shape
- x_test shape
- 자료형
- 값의 범위
- 첫 번째 뉴스 벡터의 1 개수
- 첫 번째 뉴스의 고유 단어 수
- 전체 1의 비율
- 전체 0의 비율
- 메모리 사용량

이 입력표현을 다음과 같이 설명하여라.

- 여러 단어 위치가 동시에 1
- 멀티-핫 인코딩
- Binary Bag-of-Words
- 단어 등장 여부 사용
- 단어 순서 손실
- 반복 횟수 손실

────────────────────────────────────
10. 레이블 처리
────────────────────────────────────

다음 두 방식을 설명하여라.

[방식 A]

- 46차원 원-핫 레이블
- categorical_crossentropy

[방식 B]

- 정수 레이블 0~45
- sparse_categorical_crossentropy

기본 실습에서는 정수 레이블 방식 사용을 권장하여라.

y_train = np.asarray(train_labels).astype("int32")
y_test = np.asarray(test_labels).astype("int32")

컴파일:

loss="sparse_categorical_crossentropy"

교재 재현을 위해 원-핫 방식도 별도로 설명할 수 있다.

────────────────────────────────────
11. 훈련·검증·시험자료 구성
────────────────────────────────────

시험자료 2,246개는 최종평가용으로 유지하여라.

훈련자료 8,982개 중 1,000개를 검증자료로 분리하여라.

가능하면 다음 층화분할을 사용하여라.

from sklearn.model_selection import train_test_split

partial_x_train, x_val, partial_y_train, y_val = train_test_split(
    x_train,
    y_train,
    test_size=1000,
    stratify=y_train,
    random_state=42
)

층화분할이 실패하면 다음을 수행하여라.

1. 실패 원인을 확인한다.
2. 클래스별 최소 표본 수를 제시한다.
3. test_size를 조정하거나
4. 희소 클래스가 각 분할에 포함되도록 직접 분할하거나
5. 교재 방식의 앞부분 분할을 사용하되 한계를 설명한다.

다음을 출력하여라.

- 부분 훈련자료 수
- 검증자료 수
- 시험자료 수
- 각 자료의 클래스 수
- 각 자료의 토픽별 분포
- 훈련·검증 분포 차이

────────────────────────────────────
12. DNN 다중분류 기본개념
────────────────────────────────────

다음을 학생 수준에 맞게 설명하여라.

- Text Classification
- Single-label Multiclass Classification
- Dense Layer
- Input Layer
- Hidden Layer
- Output Layer
- Neuron
- Weight
- Bias
- ReLU
- Softmax
- Categorical Cross-Entropy
- Sparse Categorical Cross-Entropy
- Forward Propagation
- Backpropagation
- Epoch
- Batch Size
- Learning Rate
- Overfitting
- Generalization
- Bottleneck

본 모델:

- 입력노드: 10,000
- 은닉층 1: 64
- 은닉층 2: 64
- 출력층: 46
- 출력 활성화: Softmax
- 출력: 토픽별 확률

────────────────────────────────────
13. 기본 DNN 구축
────────────────────────────────────

최신 Keras 문법을 사용하여라.

model = keras.Sequential([
    keras.Input(shape=(10000,)),
    layers.Dense(64, activation="relu"),
    layers.Dense(64, activation="relu"),
    layers.Dense(46, activation="softmax")
])

컴파일:

model.compile(
    optimizer="rmsprop",
    loss="sparse_categorical_crossentropy",
    metrics=["accuracy"]
)

다음을 출력하여라.

- model.summary()
- 각 층의 입력 shape
- 각 층의 출력 shape
- 층별 파라미터 수
- 전체 파라미터 수
- 학습 가능한 파라미터 수

────────────────────────────────────
14. 파라미터 수 계산
────────────────────────────────────

다음을 직접 계산하여라.

첫 번째 Dense:

10000 × 64 + 64

두 번째 Dense:

64 × 64 + 64

출력층:

64 × 46 + 46

전체 파라미터 수가 model.summary()와 일치하는지 확인하여라.

────────────────────────────────────
15. 기본모형 실제 학습
────────────────────────────────────

다음 조건으로 학습하여라.

- Epoch: 20
- Batch size: 512
- Optimizer: RMSprop
- Validation data 사용

history = model.fit(
    partial_x_train,
    partial_y_train,
    epochs=20,
    batch_size=512,
    validation_data=(x_val, y_val),
    verbose=1
)

다음을 실제 표로 작성하여라.

| Epoch | Train Loss | Valid Loss | Train Acc | Valid Acc |
|------|------------|------------|-----------|-----------|

다음을 출력하여라.

- 전체 학습시간
- Epoch당 평균 학습시간
- 최저 Validation Loss
- 최고 Validation Accuracy
- 해당 Epoch

────────────────────────────────────
16. 학습곡선
────────────────────────────────────

다음 그래프를 별도로 작성하여라.

1. Training Loss와 Validation Loss
2. Training Accuracy와 Validation Accuracy

다음을 해석하여라.

- 훈련손실이 감소하는가?
- 검증손실의 최솟값은 몇 Epoch인가?
- 검증손실이 다시 증가하는가?
- 훈련정확도와 검증정확도의 차이가 커지는가?
- 교재처럼 9 Epoch 부근에서 과적합이 나타나는가?
- 실제 결과가 다르면 몇 Epoch에서 나타나는가?

────────────────────────────────────
17. 최적 Epoch 결정
────────────────────────────────────

다음을 실제 계산하여라.

best_epoch_loss = np.argmin(
    history.history["val_loss"]
) + 1

best_epoch_accuracy = np.argmax(
    history.history["val_accuracy"]
) + 1

두 Epoch가 다르면
Validation Loss를 우선 기준으로 최적 Epoch를 선택하여라.

선정 이유를 설명하여라.

교재의 9 Epoch를 그대로 고정하지 마라.

────────────────────────────────────
18. Early Stopping
────────────────────────────────────

다음 Callback을 적용한 모델을 별도로 학습하여라.

early_stopping = keras.callbacks.EarlyStopping(
    monitor="val_loss",
    patience=2,
    restore_best_weights=True
)

최대 Epoch:

30

다음을 출력하여라.

- 실제 학습 Epoch 수
- 최저 Validation Loss
- 최고 Validation Accuracy
- 조기종료 여부
- 복원된 최적 Epoch

기본 20 Epoch 모델과 비교하여라.

────────────────────────────────────
19. 최적 Epoch 재학습
────────────────────────────────────

검증자료로 결정한 best_epoch를 이용하여
새로운 모델을 처음부터 생성하여라.

전체 훈련자료 8,982개를 사용하여
best_epoch만큼 학습하여라.

시험자료는 학습에 사용하지 마라.

최종모형 구조:

- Dense 64
- Dense 64
- Dense 46 Softmax

────────────────────────────────────
20. 시험자료 최종평가
────────────────────────────────────

시험자료로 다음을 평가하여라.

- Test Loss
- Test Accuracy
- 최종 Epoch
- Train–Test Accuracy 차이

첨부 교재의 과거 시험 정확도 약 0.787을
현재 실행결과로 사용하지 마라.

현재 Python 실행결과만 제시하여라.

────────────────────────────────────
21. 예측확률과 클래스
────────────────────────────────────

다음을 수행하여라.

pred_prob = final_model.predict(x_test)
pred_class = np.argmax(pred_prob, axis=1)

다음을 실제 확인하여라.

- 예측확률 shape
- 첫 번째 예측확률 shape
- 첫 번째 예측확률 합
- 예측확률 최솟값
- 예측확률 최댓값
- 첫 번째 예측 클래스
- 실제 클래스
- 정오 여부

다음 표를 작성하여라.

| Actual Topic | Predicted Topic | Max Probability | Correct |
|-------------|-----------------|-----------------|---------|

앞부분 20개를 출력하여라.

────────────────────────────────────
22. Top-k Accuracy
────────────────────────────────────

다음을 계산하여라.

- Top-1 Accuracy
- Top-3 Accuracy
- Top-5 Accuracy

Top-k Accuracy의 의미를 설명하여라.

예:

- 실제 토픽이 가장 높은 확률 1개 안에 포함
- 실제 토픽이 상위 3개 후보에 포함
- 실제 토픽이 상위 5개 후보에 포함

46개 클래스 문제에서는 Top-3와 Top-5도 유용하다고 설명하여라.

────────────────────────────────────
23. 혼동행렬
────────────────────────────────────

46×46 혼동행렬을 계산하여라.

- 행: 실제 토픽
- 열: 예측 토픽

다음 두 형태로 시각화하여라.

1. 원자료 혼동행렬
2. 행 기준 정규화 혼동행렬

46×46 전체 그래프가 복잡하면 다음을 추가하여라.

- 빈도가 높은 상위 15개 토픽 혼동행렬
- 가장 많이 혼동된 토픽쌍
- 소수 클래스 혼동행렬

────────────────────────────────────
24. 클래스별 성능
────────────────────────────────────

각 토픽에 대해 다음을 계산하여라.

- Precision
- Recall
- F1-score
- Support

다음 평균을 제시하여라.

- Macro Precision
- Macro Recall
- Macro F1
- Weighted Precision
- Weighted Recall
- Weighted F1

다음 표를 작성하여라.

| Topic | Precision | Recall | F1 | Support |
|------|-----------|--------|----|---------|

다음을 분석하여라.

- Recall이 가장 높은 토픽
- Recall이 가장 낮은 토픽
- F1이 가장 높은 토픽
- F1이 가장 낮은 토픽
- 표본 수와 F1의 관계
- 소수 토픽의 성능

────────────────────────────────────
25. Accuracy와 Macro F1 비교
────────────────────────────────────

다음을 설명하여라.

Accuracy:

- 전체 정답 비율
- 다수 클래스 영향이 큼

Macro F1:

- 46개 토픽별 F1의 단순평균
- 소수 클래스도 동일한 비중

Weighted F1:

- 클래스별 표본 수를 가중치로 반영
- 다수 클래스 영향이 큼

세 지표를 실제 수치로 비교하여라.

────────────────────────────────────
26. 자주 혼동되는 토픽쌍
────────────────────────────────────

혼동행렬의 대각선을 제외하고
오분류 빈도가 높은 토픽쌍 상위 15개를 추출하여라.

다음 표를 작성하여라.

| Rank | Actual Topic | Predicted Topic | Count |
|------|--------------|-----------------|-------|

해당 토픽쌍의 대표 뉴스기사를 복원하여 비교하여라.

실제 토픽 이름은 임의로 만들지 마라.

────────────────────────────────────
27. 오분류 뉴스 분석
────────────────────────────────────

오분류된 시험뉴스를 추출하여라.

다음 유형을 각각 제시하여라.

1. 높은 확률로 잘못 분류한 뉴스
2. 낮은 확률로 잘못 분류한 뉴스
3. Top-3에는 실제 토픽이 포함된 오분류
4. Top-5에도 실제 토픽이 없는 오분류
5. 가장 짧은 오분류 뉴스
6. 가장 긴 오분류 뉴스
7. 소수 클래스 오분류 뉴스

다음 표를 작성하여라.

| Actual | Predicted | Probability | Length | News Text |
|--------|-----------|-------------|--------|-----------|

뉴스가 길면 앞부분만 제시하여라.

────────────────────────────────────
28. 예측 불확실성
────────────────────────────────────

각 뉴스에 대해 다음을 계산하여라.

- 최대 예측확률
- 두 번째 예측확률
- 두 확률 차이
- 예측 엔트로피

다음 유형을 제시하여라.

- 확신이 높은 정답
- 확신이 낮은 정답
- 확신이 높은 오답
- 확신이 낮은 오답

46개 클래스에서는 최대확률이 낮고
상위 두 확률 차이가 작을수록
모델 판단이 불확실할 수 있음을 설명하여라.

────────────────────────────────────
29. 병목층 비교
────────────────────────────────────

다음 모델을 비교하여라.

- (64,64)
- (64,32)
- (64,16)
- (64,8)
- (64,4)

각 모델의 두 번째 은닉층 크기만 변경하여라.

다음을 비교하여라.

- 파라미터 수
- Validation Loss
- Validation Accuracy
- Test Accuracy
- Macro F1
- Weighted F1
- 학습시간

다음 표를 작성하여라.

| Structure | Params | Valid Acc | Test Acc | Macro F1 | Time |
|-----------|--------|-----------|----------|----------|------|

Dense 4가 성능을 낮춘다면
정보 병목 가능성으로 해석하여라.

단, 작은 병목층이 항상 나쁘다고 단정하지 마라.

────────────────────────────────────
30. 은닉층 구조 비교
────────────────────────────────────

다음 구조를 비교하여라.

- Dense 32
- Dense 64
- Dense 128
- Dense 64 → Dense 64
- Dense 128 → Dense 64
- Dense 128 → Dense 64 → Dense 32

다음을 비교하여라.

- 파라미터 수
- 최고 Validation Accuracy
- 최저 Validation Loss
- Test Accuracy
- Macro F1
- 과적합 정도
- 학습시간

성능 차이가 작으면 더 단순한 구조를 선택하여라.

────────────────────────────────────
31. Dropout 비교
────────────────────────────────────

다음 Dropout을 비교하여라.

- 0
- 0.2
- 0.3
- 0.5

예:

model = keras.Sequential([
    keras.Input(shape=(10000,)),
    layers.Dense(64, activation="relu"),
    layers.Dropout(0.3),
    layers.Dense(64, activation="relu"),
    layers.Dropout(0.3),
    layers.Dense(46, activation="softmax")
])

다음을 비교하여라.

- Train Accuracy
- Validation Accuracy
- Test Accuracy
- Macro F1
- 과적합 시작 Epoch

────────────────────────────────────
32. L2 정규화
────────────────────────────────────

다음 L2 계수를 비교하여라.

- 0
- 0.0001
- 0.001
- 0.01

다음을 비교하여라.

- Train Loss
- Validation Loss
- Test Accuracy
- Macro F1
- 일반화 차이

────────────────────────────────────
33. Batch size 비교
────────────────────────────────────

다음 Batch size를 비교하여라.

- 64
- 128
- 256
- 512

다음을 비교하여라.

- Steps per Epoch
- 학습시간
- Validation Accuracy
- Test Accuracy
- Macro F1

────────────────────────────────────
34. Optimizer 비교
────────────────────────────────────

다음 Optimizer를 비교하여라.

- SGD
- RMSprop
- Adam

동일한 모델구조와 Epoch를 사용하여라.

다음을 비교하여라.

- 수렴속도
- Validation Loss
- Validation Accuracy
- Test Accuracy
- Macro F1
- 학습시간

────────────────────────────────────
35. 입력 단어 수 비교
────────────────────────────────────

다음 num_words를 비교하여라.

- 1,000
- 5,000
- 10,000
- 20,000

각 설정에서 데이터를 다시 불러오고
입력차원에 맞게 모델을 생성하여라.

다음을 비교하여라.

- 입력차원
- 파라미터 수
- 메모리 사용량
- 학습시간
- Test Accuracy
- Macro F1

단어 수가 많다고 항상 성능이 증가하지 않음을 설명하여라.

────────────────────────────────────
36. 클래스 불균형 대응
────────────────────────────────────

토픽별 클래스 불균형을 확인한 후
다음 방법을 비교하여라.

1. 기본모형
2. class_weight 사용
3. Focal Loss가 가능한 경우
4. 소수 클래스 가중치 증가

class_weight는 훈련자료 기준으로 계산하여라.

시험자료에는 가중치를 적용하지 마라.

다음을 비교하여라.

- Accuracy
- Macro Recall
- Macro F1
- Weighted F1
- 소수 클래스 Recall

전체 Accuracy가 조금 감소하더라도
Macro F1과 소수 클래스 Recall이 개선될 수 있음을 설명하여라.

────────────────────────────────────
37. 기준모형 비교
────────────────────────────────────

DNN과 다음 기준모형을 비교하여라.

- DummyClassifier
- Multinomial Naive Bayes
- Logistic Regression
- Linear SVM
- DNN

입력자료:

- Binary Bag-of-Words
- 가능하면 TF-IDF

다음 표를 작성하여라.

| Model | Accuracy | Macro F1 | Weighted F1 | Time |
|-------|----------|----------|-------------|------|

DNN이 항상 가장 높은 성능을 보인다고 가정하지 마라.

────────────────────────────────────
38. Embedding 기반 모델
────────────────────────────────────

정수 시퀀스 기반 Embedding 모델을 구축하여라.

뉴스 길이를 동일하게 맞추기 위해 Padding하여라.

예:

maxlen = 300

x_train_seq = keras.utils.pad_sequences(
    train_data,
    maxlen=maxlen
)

x_test_seq = keras.utils.pad_sequences(
    test_data,
    maxlen=maxlen
)

Embedding 모델:

embedding_model = keras.Sequential([
    keras.Input(shape=(maxlen,)),
    layers.Embedding(
        input_dim=10000,
        output_dim=64
    ),
    layers.GlobalAveragePooling1D(),
    layers.Dense(64, activation="relu"),
    layers.Dense(46, activation="softmax")
])

다음을 비교하여라.

- Bag-of-Words DNN
- Embedding DNN

평가:

- Accuracy
- Macro F1
- Weighted F1
- 파라미터 수
- 학습시간

────────────────────────────────────
39. 새로운 뉴스 예측
────────────────────────────────────

사용자가 입력한 영어 뉴스기사를
46개 Topic 중 하나로 분류하여라.

다음 과정을 수행하여라.

1. 소문자 변환
2. 기본 토큰화
3. Reuters word_index를 이용한 인덱스 변환
4. 상위 num_words 범위만 유지
5. 멀티-핫 벡터 생성
6. Softmax 확률 예측
7. Top-1, Top-3, Top-5 토픽 출력

다음 표를 작성하여라.

| Rank | Topic | Probability |
|------|-------|-------------|

토픽 이름 매핑이 없으면
Topic 번호로만 제시하여라.

외부 뉴스의 전처리가 Reuters 데이터와 완전히 같지 않을 수 있으므로
예측은 시범적 결과로 설명하여라.

────────────────────────────────────
40. 최종모형 선정
────────────────────────────────────

다음 후보를 비교하여라.

- 교재 기본 DNN
- Early Stopping DNN
- Dropout DNN
- L2 DNN
- 클래스 가중치 DNN
- 최적 병목층 DNN
- Embedding DNN
- Logistic Regression
- Linear SVM

다음 표를 작성하여라.

| Model | Accuracy | Macro F1 | Weighted F1 | Params | Time |
|-------|----------|----------|-------------|--------|------|

다음을 종합하여 최종모형을 선정하여라.

- Validation Loss
- Test Accuracy
- Macro F1
- Weighted F1
- 소수 클래스 Recall
- 파라미터 수
- 학습시간
- 과적합 정도
- 구조 단순성
- 해석 가능성

성능 차이가 작으면 더 단순하고 안정적인 모형을 선택하여라.

────────────────────────────────────
41. 분석의 한계
────────────────────────────────────

다음을 실제 결과와 연결하여 설명하여라.

- 토픽별 표본 수가 불균형함
- 일부 토픽의 표본 수가 매우 적음
- 멀티-핫 방식은 단어 순서를 잃음
- 단어 반복 횟수를 반영하지 않음
- 상위 10,000개 단어만 사용함
- 토픽 번호의 실제 의미가 데이터에 직접 제공되지 않음
- 텍스트 문맥과 문장 구조를 충분히 활용하지 못함
- 외부 뉴스 전처리는 Reuters 데이터와 다를 수 있음
- 시험자료를 반복 확인하면 사실상 검증자료처럼 사용될 수 있음
- 높은 Accuracy가 모든 토픽에서 높은 성능을 의미하지 않음
- Macro F1과 클래스별 Recall을 함께 확인해야 함

────────────────────────────────────
42. 결과파일 저장
────────────────────────────────────

다음 CSV 파일을 생성하여라.

- reuters_data_summary.csv
- reuters_class_distribution.csv
- reuters_article_length.csv
- reuters_training_history.csv
- reuters_test_predictions.csv
- reuters_confusion_matrix.csv
- reuters_classification_report.csv
- reuters_topk_accuracy.csv
- reuters_confusion_pairs.csv
- reuters_misclassified_articles.csv
- reuters_uncertain_predictions.csv
- reuters_bottleneck_comparison.csv
- reuters_architecture_comparison.csv
- reuters_dropout_comparison.csv
- reuters_l2_comparison.csv
- reuters_optimizer_comparison.csv
- reuters_vocabulary_comparison.csv
- reuters_model_comparison.csv
- reuters_new_article_predictions.csv
- reuters_final_results.csv

다음 Excel 파일을 생성하여라.

- reuters_news_classification_results.xlsx

Excel Sheet:

- Data_Summary
- Class_Distribution
- Article_Length
- Training_History
- Test_Predictions
- Confusion_Matrix
- Classification_Report
- TopK_Accuracy
- Confusion_Pairs
- Misclassified_Articles
- Uncertain_Predictions
- Bottleneck_Comparison
- Architecture_Comparison
- Dropout_Comparison
- L2_Comparison
- Optimizer_Comparison
- Vocabulary_Comparison
- Model_Comparison
- New_Article_Predictions
- Final_Results

다음 PNG 파일을 생성하여라.

- reuters_class_distribution.png
- reuters_class_distribution_log.png
- reuters_article_length_distribution.png
- reuters_training_validation_loss.png
- reuters_training_validation_accuracy.png
- reuters_confusion_matrix.png
- reuters_normalized_confusion_matrix.png
- reuters_top_topics_confusion_matrix.png
- reuters_class_f1_scores.png
- reuters_support_vs_f1.png
- reuters_bottleneck_comparison.png
- reuters_architecture_comparison.png
- reuters_dropout_comparison.png
- reuters_optimizer_comparison.png
- reuters_vocabulary_comparison.png
- reuters_model_comparison.png

저장 후 실제 파일이 생성되었는지 확인하여라.

────────────────────────────────────
43. 단계별 Python 코딩
────────────────────────────────────

코드는 다음 단계로 구분하여 작성하여라.

[코딩 1단계] 실행환경과 라이브러리 확인
[코딩 2단계] 난수 seed 설정
[코딩 3단계] Reuters 데이터 불러오기
[코딩 4단계] 데이터 구조 확인
[코딩 5단계] 토픽별 클래스 분포
[코딩 6단계] 뉴스 길이 분석
[코딩 7단계] 단어 인덱스 확인
[코딩 8단계] 뉴스기사 영어 복원
[코딩 9단계] 멀티-핫 벡터화
[코딩 10단계] 입력자료 희소도 확인
[코딩 11단계] 레이블 처리
[코딩 12단계] 훈련·검증·시험자료 구성
[코딩 13단계] DNN 다중분류 원리
[코딩 14단계] 기본 DNN 구축
[코딩 15단계] 파라미터 수 확인
[코딩 16단계] 20 Epoch 기본 학습
[코딩 17단계] Training·Validation Loss
[코딩 18단계] Training·Validation Accuracy
[코딩 19단계] 과적합 시점
[코딩 20단계] Early Stopping
[코딩 21단계] 최적 Epoch 재학습
[코딩 22단계] 시험자료 최종평가
[코딩 23단계] 예측확률과 예측토픽
[코딩 24단계] Top-1·Top-3·Top-5 Accuracy
[코딩 25단계] 혼동행렬
[코딩 26단계] 토픽별 Precision·Recall·F1
[코딩 27단계] Macro F1·Weighted F1
[코딩 28단계] 자주 혼동되는 토픽쌍
[코딩 29단계] 오분류 뉴스
[코딩 30단계] 예측 불확실성
[코딩 31단계] 병목층 비교
[코딩 32단계] 은닉층 구조 비교
[코딩 33단계] Dropout
[코딩 34단계] L2 정규화
[코딩 35단계] Batch size
[코딩 36단계] Optimizer
[코딩 37단계] 단어 수 비교
[코딩 38단계] 클래스 불균형 대응
[코딩 39단계] 기준모형 비교
[코딩 40단계] Embedding 모델
[코딩 41단계] 새로운 뉴스 예측
[코딩 42단계] 최종모형 선정
[코딩 43단계] 결과 저장

각 단계에서는 반드시 다음 순서를 지켜라.

1. 무엇을 하는 단계인가?
2. 왜 필요한가?
3. Python 코드
4. Python 실제 실행결과
5. 결과 해석
6. 다음 단계와의 연결

모든 단계가 끝난 뒤
처음부터 끝까지 한 번에 실행 가능한
전체 통합 Python 코드를 다시 제시하여라.

────────────────────────────────────
44. Python 코드 작성 원칙
────────────────────────────────────

기본 라이브러리:

- tensorflow
- keras
- numpy
- pandas
- matplotlib
- scikit-learn
- scipy
- openpyxl

핵심 클래스와 함수:

- keras.Sequential
- keras.Input
- layers.Dense
- layers.Dropout
- layers.Embedding
- layers.GlobalAveragePooling1D
- EarlyStopping
- ReduceLROnPlateau
- train_test_split
- confusion_matrix
- classification_report
- precision_recall_fscore_support
- top_k_accuracy_score
- LogisticRegression
- MultinomialNB
- LinearSVC

주요 코드에는 한국어 주석을 작성하여라.

그래프는 matplotlib 중심으로 작성하여라.

한글 폰트가 없으면 영문 제목을 사용하고
폰트 문제로 분석을 중단하지 마라.

────────────────────────────────────
45. 오류 발생 시 처리
────────────────────────────────────

다음 오류가 발생하면 종료하지 말고
원인을 분석하여 수정한 뒤 다시 실행하여라.

- TensorFlow 설치 오류
- Reuters 다운로드 오류
- 메모리 부족
- 멀티-핫 벡터 생성 오류
- 층화분할 오류
- 희소 클래스 오류
- 입력 shape 오류
- 레이블 shape 오류
- Softmax 출력 오류
- Loss와 레이블 형식 불일치
- NaN Loss
- predict shape 오류
- 혼동행렬 오류
- Top-k Accuracy 오류
- 외부 뉴스 인코딩 오류
- Excel 저장 오류
- 한글 폰트 오류

대안:

- Batch size 감소
- num_words 감소
- 모델 크기 감소
- sparse loss 사용
- 층화분할 크기 조정
- 클래스 가중치 사용
- Learning rate 감소
- GPU 대신 CPU 실행

수정내용과 이유를 설명한 후 다시 실행하여라.

────────────────────────────────────
46. 결과 검증
────────────────────────────────────

최종 결과 전에 다음을 확인하여라.

- 훈련자료가 8,982개인가?
- 시험자료가 2,246개인가?
- 클래스가 0~45인가?
- 고유 클래스가 46개인가?
- 입력 shape가 10,000차원인가?
- 입력이 멀티-핫 형식인가?
- 정수 레이블과 sparse loss가 일치하는가?
- 원-핫 레이블과 categorical loss가 일치하는가?
- 시험자료가 모델선정에 사용되지 않았는가?
- 출력층이 Dense(46, softmax)인가?
- 각 예측확률 합이 1인가?
- Argmax 결과가 예측토픽인가?
- 혼동행렬의 행은 실제, 열은 예측인가?
- Accuracy가 혼동행렬 대각합과 일치하는가?
- Macro F1과 Weighted F1을 모두 계산했는가?
- 소수 클래스 성능을 확인했는가?
- 최적 Epoch가 검증자료로 선택되었는가?
- 과적합 판단이 학습곡선에 근거하는가?
- 토픽 이름을 임의로 만들지 않았는가?
- 저장파일이 실제 생성되었는가?

문제가 있으면 수정한 뒤 다시 실행하여라.

────────────────────────────────────
47. 최종 답변 출력 순서
────────────────────────────────────

① 분석 목적
② 첨부 교재의 기본구조
③ 실행환경 확인
④ Reuters 데이터 구조
⑤ 단일 레이블 다중분류
⑥ 토픽별 클래스 분포
⑦ 뉴스 길이 분석
⑧ 뉴스기사 영어 복원
⑨ 멀티-핫 벡터화
⑩ 레이블 처리방식
⑪ 훈련·검증·시험자료 구성
⑫ DNN 다중분류 원리
⑬ 기본 DNN 구조
⑭ 모델 파라미터 수
⑮ 기본모형 실제 학습
⑯ Training·Validation Loss
⑰ Training·Validation Accuracy
⑱ 과적합 시점
⑲ Early Stopping
⑳ 최적 Epoch 재학습
㉑ 시험 Loss와 Accuracy
㉒ 예측확률과 예측토픽
㉓ Top-1·Top-3·Top-5 Accuracy
㉔ 혼동행렬
㉕ 토픽별 Precision·Recall·F1
㉖ Macro F1·Weighted F1
㉗ 자주 혼동되는 토픽쌍
㉘ 오분류 뉴스
㉙ 예측 불확실성
㉚ 병목층 비교
㉛ 은닉층 구조 비교
㉜ Dropout과 L2 정규화
㉝ Batch size·Optimizer
㉞ 단어 수 비교
㉟ 클래스 불균형 대응
㊱ 기준모형 비교
㊲ Embedding 모델
㊳ 새로운 뉴스 예측
㊴ 최종모형 선정
㊵ 분석의 한계
㊶ 단계별 Python 코드
㊷ Python 실제 실행결과
㊸ 전체 통합 Python 코드
㊹ 생성된 CSV·Excel·PNG 파일

모든 수치, 표, 그래프 및 결론은
실제 Python 실행결과만을 사용하여라.

────────────────────────────────────
[사용자 입력정보]
────────────────────────────────────

[분석 목적 시작]

Reuters 뉴스 데이터를 이용하여
각 뉴스기사를 46개 토픽 중 하나로 분류하는
완전연결 심층신경망을 구축하고 성능을 평가한다.

[분석 목적 끝]

[데이터 시작]

TensorFlow Keras Reuters 데이터 자동 불러오기

[데이터 끝]

[단어 수 시작]

num_words=10000

비교:
1000, 5000, 10000, 20000

[단어 수 끝]

[기본 모델 시작]

입력:
10,000차원 멀티-핫 벡터

은닉층 1:
Dense 64
activation=relu

은닉층 2:
Dense 64
activation=relu

출력층:
Dense 46
activation=softmax

Optimizer:
rmsprop

Loss:
sparse_categorical_crossentropy

Epoch:
20

Batch size:
512

Seed:
42

[기본 모델 끝]

[검증자료 시작]

훈련자료 중 1,000개
가능하면 층화분할
random_state=42

[검증자료 끝]

[Early Stopping 시작]

monitor=val_loss
patience=2
restore_best_weights=True
최대 Epoch=30

[Early Stopping 끝]

[병목층 비교 시작]

(64,64)
(64,32)
(64,16)
(64,8)
(64,4)

[병목층 비교 끝]

[비교 DNN 구조 시작]

Dense 32
Dense 64
Dense 128
Dense 64 → Dense 64
Dense 128 → Dense 64
Dense 128 → Dense 64 → Dense 32

[비교 DNN 구조 끝]

[Dropout 시작]

0, 0.2, 0.3, 0.5

[Dropout 끝]

[L2 정규화 시작]

0, 0.0001, 0.001, 0.01

[L2 정규화 끝]

[Batch size 시작]

64, 128, 256, 512

[Batch size 끝]

[Optimizer 시작]

SGD, RMSprop, Adam

[Optimizer 끝]

[클래스 불균형 대응 시작]

기본모형
class_weight 적용
소수 클래스 Recall과 Macro F1 비교

[클래스 불균형 대응 끝]

[평가지표 시작]

Test Loss
Accuracy
Macro Precision
Macro Recall
Macro F1
Weighted Precision
Weighted Recall
Weighted F1
Top-3 Accuracy
Top-5 Accuracy
클래스별 Precision
클래스별 Recall
클래스별 F1

[평가지표 끝]

[새로운 뉴스 시작]

새로운 영어 뉴스기사를 입력하면
Top-1, Top-3, Top-5 Topic 번호와 확률을 제시

새로운 뉴스가 없으면:
신규 뉴스 없음

[새로운 뉴스 끝]